package com.zkyc.framework.website.util;

import com.zkyc.framework.common.utils.DecryptDataUtil;
import com.zkyc.framework.common.utils.JschUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;


@Slf4j
public class DeployUtil {

    public static final String TEST_IP = "10.101.116.5";
    public static final String CD = "cd ";
    public static final String CP = "cp -r ";
    public static final String AND = " && ";
    public static final String NPM_BUILD = "npm run build";
    public static final String NGINX_DOMAIN_CONFIG_PATH = "/etc/nginx/conf.d/";
    public static final String NGINX_CONFIG_PATH_PREFIX = "/data/nginx/conf.d/";
    public static final String NGINX_LOG_PATH = "/data/nginx/log";
    public static final String NGINX_CONFIG = "nginx.conf";
    public static final String TOUCH = "touch ";
    public static final String NGINX_SBIN_PATH = "/usr/local/nginx/sbin";
    public static final String NGINX_RELOAD = "systemctl restart nginx";
    public static final String TEMPLATE_PATH = "/data/template/";
    public static final String WEBSITE_PATH = "/data/website/";
    public static final String DIST = "/dist";
    public static final String MAKEDIR = "mkdir -p ";
    public static final String TEMP = "temp_";

    public static void main(String[] args) {
        //deleteLastLine("C:\\Users\\Naruto\\Desktop\\新建文件夹\\demo.txt");
        //startModify("/root/station_group/template/aaaa/src/utils/request.js","config.headers.websiteId = '4'","config.headers.websiteId = '5'");
/*        startAdd("C:\\Users\\Naruto\\Desktop\\新建文件夹\\demo.txt", "        location /ZBDH/ {\n" +
                "          proxy_pass       http://10.101.116.5:8281/;\n" +
                "          proxy_set_header X-Forwarded-Proto $scheme;\n" +
                "          proxy_set_header X-Forwarded-Port $server_port;\n" +
                "          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n" +
                "          proxy_set_header Upgrade $http_upgrade;\n" +
                "          proxy_set_header Connection \"upgrade\";\n" +
                "        }");*/
        /*System.out.println(isSocketAliveUitlitybyCrunchify("localhost", 8080));
        JschUtils jschUtils = null;
        jschUtils = new JschUtils("10.100.28.125", "zjlab", "zc3VzUlELVwJ");
        jschUtils.connectSftp();
        //修改模板的websiteId
        //jschUtils.downloadFile("/data/nginx/conf.d/10/", "nginx.conf", "C:\\Users\\Naruto\\Desktop\\aaaaaaaaaaaaa\\", TEMP + "nginx,conf");
        System.out.println(jschUtils.execCmd("docker run -d -p 8762:443 -p 5664:80 --name nginx16 -v /data/nginx/conf.d/16:/etc/nginx/conf.d  -v /data/website/aaaa/16/dist:/etc/nginx/dist  -v /data/nginx/log:/var/log/nginx --restart=always  nginx:1.16.1"));*/
        //startModify("C:\\Users\\Naruto\\Desktop\\fsdownload\\app.9e929616.js", "localStorage.setItem(\"websiteIdTeap\",5)", "localStorage.setItem(\"websiteIdTeap\",0)");
        File file = new File("C:\\Users\\Naruto\\Desktop\\fsdownload\\temp_24nginx.conf");
        deleteDirectoryLegacyIO(file);
    }

    /**
     * 判断主机端口
     *
     * @return boolean - true/false
     */
    public static boolean isSocketAliveUitlitybyCrunchify(String hostName, int port) {
        boolean isAlive = false;

        // 创建一个套接字
        SocketAddress socketAddress = new InetSocketAddress(hostName, port);
        Socket socket = new Socket();

        // 超时设置，单位毫秒
        int timeout = 2000;

        log("hostName: " + hostName + ", port: " + port);
        try {
            socket.connect(socketAddress, timeout);
            socket.close();
            isAlive = true;

        } catch (SocketTimeoutException exception) {
            System.out.println("SocketTimeoutException " + hostName + ":" + port + ". " + exception.getMessage());
        } catch (IOException exception) {
            System.out.println(
                    "IOException - Unable to connect to " + hostName + ":" + port + ". " + exception.getMessage());
        }
        return isAlive;
    }

    private static void log(String string) {
        System.out.println(string);
    }

    public static void startModify(String path, String target, String replacement) {
        File file = new File(path);
        if (file.exists()) {
            modifyFileContent(file, target, replacement);
        } else {
            log.error("文件 {} 不存在", path);
        }
    }

    public static void startAdd(String path, String target) {
        File file = new File(path);
        if (file.exists()) {
            addFileContent(file, target);
        } else {
            log.error("文件 {} 不存在", path);
        }
    }

    /**
     * 修改文件中的内容
     *
     * @param file        文件
     * @param target      被替换的字符串
     * @param replacement 替换字符串
     */
    public static void modifyFileContent(File file, String target, String replacement) {
        log.info("开始修改文件：{}, 替换 {} 为 {}", file.getName(), target, replacement);
        StringBuilder sb = new StringBuilder();
        //记录修改的行数
        int cnt = 0;
        //记录替换所在的行
        int rowLine = 0;
        //换行符
        String enter = System.getProperty("line.separator");

        //printWriter原本也想放在 try-with 中，少写点代码，
        //但是一个文件不能同时读写，pw 和 br 对同一个文件操作的结果时，文件的内容被清空！！！
        //不妨试下，将 pw 申明在 try-with 中，看下运行结果。
        PrintWriter pw = null;
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            for (line = br.readLine(); line != null; line = br.readLine()) {
                rowLine++;
                if (line.contains(target)) {
                    line = line.replace(target, replacement);
                    log.info("替换所在行：{}", rowLine);
                    cnt++;
                }
                //数据暂存在 StringBuilder 中
                if (rowLine == 1) {
                    sb.append(line);
                } else {
                    sb.append(enter).append(line);
                }
            }
            pw = new PrintWriter(new FileWriter(file));
            pw.print(sb);
        } catch (FileNotFoundException e) {
            log.error("文件不存在！", e);
            System.exit(1);
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (pw != null) {
                pw.close();
            }
        }
        log.info("修改文件：{} 结束,一共替换{}行数据", file.getName(), cnt);
    }

    /**
     * 文件追加内容
     *
     * @param file   文件
     * @param target 被替换的字符串
     */
    public static void addFileContent(File file, String target) {
        log.info("开始修改文件：{}, 追加 {}", file.getName(), target);
        StringBuilder sb = new StringBuilder();
        //记录替换所在的行
        int rowLine = 0;
        //换行符
        String enter = System.getProperty("line.separator");
        //printWriter原本也想放在 try-with 中，少写点代码，
        //但是一个文件不能同时读写，pw 和 br 对同一个文件操作的结果时，文件的内容被清空！！！
        //不妨试下，将 pw 申明在 try-with 中，看下运行结果。
        PrintWriter pw = null;
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            for (line = br.readLine(); line != null; line = br.readLine()) {
                rowLine++;
                //数据暂存在 StringBuilder 中
                if (rowLine == 1) {
                    sb.append(line);
                } else {
                    sb.append(enter).append(line);
                }
            }
            sb.append(enter).append(target);
            pw = new PrintWriter(new FileWriter(file));
            pw.print(sb);
        } catch (FileNotFoundException e) {
            log.error("文件不存在！", e);
            System.exit(1);
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (pw != null) {
                pw.close();
            }
        }
        log.info("修改文件：{} 结束", file.getName());
    }

    /**
     * 删除最后一行
     *
     * @param filePath 文件
     */
    public static void deleteLastLine(String filePath) throws IOException {
        RandomAccessFile f = new RandomAccessFile(filePath, "rw");
        long length = f.length() - 1;
        byte b;
        do {
            length -= 1;
            f.seek(length);
            b = f.readByte();
        } while (b != 10);
        f.setLength(length + 1);
        f.close();
    }

    public static void deleteDirectoryLegacyIO(File file) {
        File[] list = file.listFiles();  //无法做到list多层文件夹数据
        if (list != null) {
            for (File temp : list) {     //先去递归删除子文件夹及子文件
                deleteDirectoryLegacyIO(temp);   //注意这里是递归调用
            }
        }

        if (file.delete()) {     //再删除自己本身的文件夹
            System.out.printf("删除成功 : %s%n", file);
        } else {
            System.err.printf("删除失败 : %s%n", file);
        }
    }


}